package com.zbcn.combootsecurity.vertify;

import com.zbcn.combootsecurity.service.CustomUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

	@Autowired
	private CustomUserDetailsService customUserDetailsService;

	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		// 获取用户输入的用户名和密码
		String inputName = authentication.getName();
		String inputPassword = authentication.getCredentials().toString();

		CustomWebAuthenticationDetails details = (CustomWebAuthenticationDetails) authentication.getDetails();
		String verifyCode = details.getVerifyCode();
		if(!validateVerify(verifyCode)) {
			throw new DisabledException("验证码输入错误");
		}
		// userDetails为数据库中查询到的用户信息
		UserDetails userDetails = customUserDetailsService.loadUserByUsername(inputName);

		// 如果是自定义AuthenticationProvider，需要手动密码校验
		if(!userDetails.getPassword().equals(inputPassword)) {
			throw new BadCredentialsException("密码错误");
		}
		//return new UsernamePasswordAuthenticationToken(inputName, inputPassword, userDetails.getAuthorities());
		return new UsernamePasswordAuthenticationToken(userDetails, inputPassword, userDetails.getAuthorities());
	}

	@Override
	public boolean supports(Class<?> authentication) {
		// 这里不要忘记，和UsernamePasswordAuthenticationToken比较
		return authentication.equals(UsernamePasswordAuthenticationToken.class);
	}

	private boolean validateVerify(String inputVerify) {
		//获取当前线程绑定的request对象
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		// 不分区大小写
		// 这个validateCode是在servlet中存入session的名字
		String validateCode = ((String) request.getSession().getAttribute("validateCode")).toLowerCase();
		inputVerify = inputVerify.toLowerCase();

		System.out.println("验证码：" + validateCode + "用户输入：" + inputVerify);

		return validateCode.equals(inputVerify);
	}

}
